;=============================================================================
; arch-independent part
;=============================================================================

%assign function_align 16

; Symbol prefix for C linkage
%macro cglobal 1-2+
    %ifidn __OUTPUT_FORMAT__,elf
        %ifdef PREFIX
            global _%1:function hidden
            %define %1 _%1
        %else
            global %1:function hidden
        %endif
    %else
        %ifdef PREFIX
            global _%1
            %define %1 _%1
        %else
            global %1
        %endif
    %endif
    align function_align
    %1:
    %if %0 > 1
        PROLOGUE %2
    %endif
%endmacro

extern _Gtab
extern _Mtab
SECTION .text

; Reed-Solomon encoding
; data[] is the input block, parity symbols are placed in bb[]
; bb[] may lie past the end of the data, e.g., for (255,223):
; encode_rs(&data[0],&data[223]);

;int rse32(dtype data[KK], dtype bb[NN-KK]);
cglobal rse32
        push ebp
        mov  ebp, esp
        sub  esp, 32
        push edi
        push esi
        push ebx
        mov  ebx, [ebp + 8]
        mov  esi, [ebp + 12]
        
        mov  eax, 7
.L75:   mov  dword [ebp + 4 * eax - 32], 0
        dec  eax
        jns  .L75
        
        mov  edi, 222
.L80:   xor  eax, eax
        mov  ecx, [ebp - 4]
        mov  al,  [edi + ebx]
        rol  ecx, 8
        mov  edx, [ebp - 8]
        xor  al, cl
        
        shl  edx, 8
        mov  cl, [ebp - 5]
        mov  dl, [ebp - 9]
        xor  ecx, [_Gtab + 4 * eax + 7168]
        xor  edx, [_Gtab + 4 * eax + 6144]
        mov  [ebp - 4], ecx
        mov  [ebp - 8], edx
        
        mov  ecx, [ebp - 12]
        mov  edx, [ebp - 16]
        shl  ecx, 8
        shl  edx, 8
        mov  cl, [ebp - 13]
        mov  dl, [ebp - 17]
        xor  ecx, [_Gtab + 4 * eax + 5120]
        xor  edx, [_Gtab + 4 * eax + 4096]
        mov  [ebp - 12], ecx
        mov  [ebp - 16], edx
        
        mov  ecx, [ebp - 20]
        mov  edx, [ebp - 24]
        shl  ecx, 8
        shl  edx, 8
        mov  cl,  [ebp - 21]
        mov  dl,  [ebp - 25]
        xor  ecx, [_Gtab + 4 * eax + 3072]
        xor  edx, [_Gtab + 4 * eax + 2048]
        mov  [ebp - 20], ecx
        mov  [ebp - 24], edx
        
        mov  ecx, [ebp - 28]
        mov  edx, [ebp - 32]
        shl  ecx, 8
        shl  edx, 8
        mov  cl,  [ebp - 29]
        xor  ecx, [_Gtab + 4 * eax + 1024]
        xor  edx, [_Gtab + 4 * eax]
        mov  [ebp - 28], ecx
        mov  [ebp - 32], edx
        
        dec  edi
        jns  .L80
        
        mov  edx, 7
.L85:   mov  eax, [ebp + 4 * edx - 32]
        mov  [esi + 4 * edx], eax
        dec  edx
        jns  .L85
        
        xor  eax, eax
        lea  esp, [ebp - 44]
        pop  ebx
        pop  esi
        pop  edi
        mov  esp, ebp
        pop  ebp
        ret


%macro  DOSYN 1
        xor  eax, eax
        xor  ebx, ebx
        xor  ecx, ecx
        xor  edx, edx

        mov  edi, 254
%%loop: mov  al, [_Mtab + 256 * %1 + eax]
        mov  ah, [edi + esi]
        mov  bl, [_Mtab + 256 * (%1 + 1) + ebx]
        mov  cl, [_Mtab + 256 * (%1 + 2) + ecx]
        mov  dl, [_Mtab + 256 * (%1 + 3) + edx]
        xor  al, ah
        xor  bl, ah
        xor  cl, ah
        xor  dl, ah
        xor  ah, ah
        dec  edi
        jns  %%loop
        mov  edi, [ebp + 12]
        mov  [%1 + edi], al
        mov  [%1 + 1 + edi], bl
        mov  [%1 + 2 + edi], cl
        mov  [%1 + 3 + edi], dl
%endmacro

; Reed-Solomon erasures-and-errors decoding
; The received block goes into data[], and a list of zero-origin
; erasure positions, if any, goes in eras_pos[] with a count in no_eras.
;
; The decoder corrects the symbols in place, if possible and returns
; the number of corrected symbols. If the codeword is illegal or
; uncorrectible, the data array is unchanged and -1 is returned

;void rssyndrome(dtype data[NN], dtype st[NN-KK]); 
cglobal rssyndrome 
        push ebp
        mov  ebp, esp
        push edi
        push esi
        push ebx
        mov  esi, [ebp + 8]
        
        DOSYN 0
        DOSYN 4
        DOSYN 8
        DOSYN 12
        DOSYN 16
        DOSYN 20
        DOSYN 24
        DOSYN 28
        
        pop  ebx
        pop  esi
        pop  edi
        pop  ebp
        ret

